ActiveAdmin.register_page "BlockDashboard" do
  menu priority: 20, label: '板块看板'

  content title: "" do
    #   div do
    #     h3 "每隔5分钟看上升的板块、资金流入的板块"
    #     h6 "查看板块详情，资金流入的个股，加入choice"
    #     h6 "购买资金持续流入，涨幅低于2.5的股票"
    #   end
    #   # 交易时间每隔15分钟
    times = %w[09:31 09:40 09:45 10:00 10:15 10:30 10:45 11:00 11:15 11:30 13:00 13:15 13:30 13:45 14:00 14:15 14:30 14:45 14:55 15:00]

    block_flows = BlockFlow.where(created_at: Time.current.beginning_of_day..Time.current.end_of_day)
    block_flows_datas = block_flows.group_by { |x| x.name }.map do |name, block_flow|
      block_flow_by_time = block_flow.group_by { |x| x.created_at.strftime("%H:%M") }
      net_amounts = times.map do |time|
        bf = block_flow_by_time[time] || []
        bf.empty? ? 0 : bf.first.net_amount
      end
      { name: name,
        data: net_amounts,
        type: "line",
        markPoint: {
          data: [
            { type: "max", name: "Max" },
            { type: "min", name: "Min" }] } }
    end
    block_flows_datas = block_flows_datas.sort_by { |x| x[:data].last.to_i }.reverse!

    gn_bases = BlockFlow.where(cate_type: "N", mark: "base").last(50)
    gn_olds = BlockFlow.where(cate_type: "N", mark: "old").last(50)

    hy_bases = BlockFlow.where(cate_type: "I", mark: "base").last(50)
    hy_olds = BlockFlow.where(cate_type: "I", mark: "old").last(50)

    trade_date_10 = trade_date(10)
    puts '【调试用】3日均线转折的板块名'
    # 3日均线转折的板块名
    gn_hy_bases = Parallel.map(gn_bases + hy_bases, in_processes: 8, progress: true) do |blk|
      block = Block.find_by_name blk.name
      next if block.nil?
      ths_daily = $TusharePro.tushare_pro("ths_daily", ts_code: block.ts_code, "start_date": trade_date_10, "end_date": Time.now.strftime("%Y%m%d"))
      next if ths_daily.count < 4
      ths_daily.shift if ths_daily.first["close"].nil?
      close_10days = if ths_daily.first["trade_date"] == Time.now.strftime("%Y%m%d")
                       ths_daily.pluck("close")
                     else
                       ths_daily.pluck("close").unshift(blk["index"].to_f)
                     end

      averages = close_10days.each_cons(3).map { |days| (days.sum / 3).round(2) }
      blk["name"] if averages[2] > averages[1] && averages[0] > averages[1]
    end

    # 所有 hy_bases + gn_bases 的涨幅图数据
    ts_codes = (hy_bases + gn_bases).pluck(:name).map { |x| Block.find_by_name(x)&.ts_code }.compact.join(",")
    ths_dailies = $TusharePro.tushare_pro("ths_daily", ts_code: ts_codes, "start_date": trade_date_10, "end_date": Time.now.strftime("%Y%m%d")).select { |x| !x["close"].nil? }
    gn_hy_bases_chart_datas = []
    ths_dailies.group_by { |x| x["ts_code"] }.each do |ts_code, ths_daily|
      block = Block.find_by_ts_code ts_code
      next if block.nil?
      data = ths_daily.pluck("pct_change").map { |x| x.to_f.round(2) }.reverse
      # data = data.each_with_object([]) { |value, result| result << value + (result.last || 0) }
      gn_hy_bases_chart_datas << {
        name: block.name,
        data: data,
        type: "line",
        markPoint: {
          data: [
            { type: "max", name: "Max" },
            { type: "min", name: "Min" }
          ]
        },
      }
    end

    # 自选板块的涨幅图数据
    is_choice_arr, is_choice_trend_arr = [false, true].map do |cumulative|
      Parallel.map(Block.is_choice?.first(10), in_processes: 4, progress: true) do |block|
        ths_daily = $TusharePro.tushare_pro("ths_daily", ts_code: block.ts_code, "start_date": trade_date_10, "end_date": Time.now.strftime("%Y%m%d"))
        ths_daily.shift if ths_daily.first["close"].nil?
        data = ths_daily.pluck("pct_change").map { |x| x.to_f.round(2) }.reverse
        data = data.each_with_object([]) { |value, result| result << value + (result.last || 0) } if cumulative
        {
          name: block.name,
          data: data,
          type: "line",
          markPoint: {
            data: [
              { type: "max", name: "Max" },
              { type: "min", name: "Min" }
            ]
          },
        }
      end
    end

    sse = $TusharePro.tushare_pro("trade_cal", "exchange": "SSE", "start_date": (Time.now - 40.day).strftime("%Y%m%d"), "end_date": (Time.now).strftime("%Y%m%d")).select { |sse| sse["is_open"] == 1 }
    dates = sse[0..9].pluck("cal_date").map { |x| x[4..7] }.reverse
    puts '【调试用】全部板块资金流情况'
    columns do
      panel '全部板块资金流情况' do
        div do
          h3 "看图说明"
          h6 "1. 图一震荡，图二逐渐上升，说明是震荡总体上升趋势。可以等图一下跌第二天关注"
          h6 "2. 图一连续上升，说明是强势连续上涨，可关注追涨"
        end
        div id: 'flow_all', style: "width: 100%; height: 5888px;"
        script <<~JS.html_safe
          var chartDom11 = document.getElementById('flow_all');
          var myChart11 = echarts.init(chartDom11);
          var option11 = {
            tooltip: { trigger: 'axis' },
            legend: {
            },
            toolbox: {
              show: true,
              feature: {
                dataZoom: { yAxisIndex: 'none' },
                dataView: { readOnly: false },
                magicType: { type: ['line', 'bar'] },
                restore: {},
                saveAsImage: {}
              }
            },
            xAxis: {
              type: 'category',
              boundaryGap: false,
              data: #{times.to_json.html_safe}
            },
            yAxis: { type: 'value' },
            series: #{raw(block_flows_datas.to_json)},
          };
          option11 && myChart11.setOption(option11);
          myChart11.on('mouseover', function(params) {
            console.log(params.seriesName);
          });
        JS
      end
      ["main", "main1"].each_with_index do |id, index|
        panel "板块趋势图#{index + 1}" do
          div id: id, style: "width: 100%; height: 588px;"
          script <<~JS.html_safe
            var chartDom = document.getElementById('#{id}');
            var myChart = echarts.init(chartDom);
            var option = {
              tooltip: { trigger: 'axis' },
              legend: {},
              toolbox: {
                show: true,
                feature: {
                  dataZoom: { yAxisIndex: 'none' },
                  dataView: { readOnly: false },
                  magicType: { type: ['line', 'bar'] },
                  restore: {},
                  saveAsImage: {}
                }
              },
              xAxis: {
                type: 'category',
                boundaryGap: false,
                data: #{raw dates}
              },
              yAxis: { type: 'value' },
              series: #{index.zero? ? raw(is_choice_arr.to_json) : raw(is_choice_trend_arr.to_json)},
            };
            option && myChart.setOption(option);
            myChart.on('mouseover', function(params) {
              console.log(params.seriesName);
            });
            myChart.on('click', function(params) {
              var blockId = #{Block.all.index_by(&:name).transform_values(&:id).to_json.html_safe}[params.seriesName];
              window.open("https://wyyzrx.com/admin/blocks/" + blockId, '_blank');
            });
          JS
        end
      end
    end
    puts '【调试用】gn_olds、gn_bases、hy_olds、hy_bases'
    columns do
      column do
        panel "gn_olds" do
          table_for gn_olds.reverse do
            column :name do |l|
              block = Block.find_by_name l.name
              block.present? ? link_to( "#{l.name}", admin_block_path(block.id)) : "#{l.name}"
            end
            column :change
            column :net_amount
            column :count
            column :is_choice
          end
        end
      end
      column do
        panel "gn_bases #{BlockFlow.last.created_at.strftime("%H:%M")}" do
          table_for gn_bases.reverse do
            column :order do |block|
              50 - gn_bases.find_index { |x| x.name == block.name }
            end
            column :name do |l|
              block = Block.find_by_name l.name
              block.present? ? link_to("#{l.name}", admin_block_path(block.id)) : "#{l.name}"
            end
            column :change
            column :net_amount
            column :net_change do |block|
              old = gn_olds.select { |x| x.name == block.name }.first
              if old.nil?
                '新晋概念'
              else
                (block.net_amount.to_f - gn_olds.select { |x| x.name == block.name }.first&.net_amount.to_f).round(2)
              end
            end
            column :order do |block|
              base_order = 50 - gn_bases.find_index { |x| x.name == block.name }
              old_order = gn_olds.find_index { |x| x.name == block.name }
              if old_order.nil?
                '新晋概念'
              else
                (50 - old_order.to_i) - base_order
              end
            end
            column :count
            column :is_choice
            column '3avg' do |l|
              if gn_hy_bases.include? l.name
                "3日均线转折"
              else
                "OTHER"
              end
            end
          end
        end
      end
    end
    columns do
      column do
        panel "hy_olds" do
          table_for hy_olds.reverse do
            column :name do |l|
              block = Block.find_by_name l.name
              block.present? ? link_to("#{l.name}", admin_block_path(block.id)) : "#{l.name}"
            end
            column :change
            column :net_amount
            column :count
            column :is_choice
          end
        end
      end
      column do
        panel "hy_bases" do
          table_for hy_bases.reverse do
            column :name do |l|
              block = Block.find_by_name l.name
              block.present? ? link_to( "#{l.name}", admin_block_path(block.id)) : "#{l.name}"
            end
            column :change
            column :net_amount
            column :count
            column :is_choice
            column '3avg' do |l|
              if gn_hy_bases.include? l.name
                "3日均线转折"
              else
                "OTHER"
              end
            end
          end
        end
      end
    end
    puts '【调试用】全部板块趋势'
    columns do
      panel '全部板块趋势' do
        div id: 'tu1', style: "width: 100%; height: 588px;"
        script <<~JS.html_safe
          var chartDom1 = document.getElementById('tu1');
          var myChart1 = echarts.init(chartDom1);
          var option1 = {
            tooltip: { trigger: 'axis' },
            legend: {
              selected: #{gn_hy_bases_chart_datas.map { |data| [data[:name], false] }.to_h.to_json} // 默认所有折线不显示
            },
            toolbox: {
              show: true,
              feature: {
                dataZoom: { yAxisIndex: 'none' },
                dataView: { readOnly: false },
                magicType: { type: ['line', 'bar'] },
                restore: {},
                saveAsImage: {}
              }
            },
            xAxis: {
              type: 'category',
              boundaryGap: false,
              data: #{dates.to_json.html_safe}
            },
            yAxis: { type: 'value' },
            series: #{ 1 ? raw(gn_hy_bases_chart_datas.to_json) : raw(is_choice_trend_arr.to_json)},
          };
          option1 && myChart1.setOption(option1);
        JS
      end
    end
    puts '【调试用】最近20个交易日的板块涨幅'
    8.times do |time|
      columns do
        (1..5).each do |i|
          date = trade_date(time * 5 + i)
          column do
            panel "#{date}" do
              records = BlockFlow.where(created_at: Time.parse(date).beginning_of_day..Time.parse(date).end_of_day, mark: "base").select { |x| x.change.to_f > 1 }
              table_for records.reverse do
                column :name do |l|
                  block = Block.find_by_name l.name
                  block.present? ? link_to( "#{l.name} - #{l.cate_type}", admin_block_path(block.id)) : "#{l.name}"
                end
                column :change
                column :net_amount
              end
            end
          end
        end
      end
    end
    puts '【调试用】最近20个交易日的板块涨幅 - Block.is_choice? ｜ block_flows：base 的涨幅change'
    # chart block_choice 的数据
    block_flows = BlockFlow.where(mark: "base", created_at: 1.month.ago.beginning_of_day..Time.now.end_of_day).select { |x| x.change.to_f > 1 }
    block_flow_names = Block.is_choice?.pluck(:name)
    x_axis = 20.times.map { |x| trade_date(x + 1) }
    y_axis = block_flow_names.map do |name|
      dates = []
      x_axis.each do |date|
        block_flow = block_flows.find { |x| x.name == name && x.created_at.strftime("%Y%m%d") == date }
        if block_flow.present?
          dates << block_flow.change.to_f
        else
          dates << 0
        end
      end
      {
        name: name,
        data: dates,
        type: "line",
        markPoint: {
          data: [
            { type: "max", name: "Max" },
            { type: "min", name: "Min" }
          ]
        },
      }
    end
    columns do
      panel '最近20个交易日 Block.is_choice: true ｜ block_flows：base 的涨幅change' do
        div id: 'block_choice', style: "width: 100%; height: 888px;"
        script <<~JS.html_safe
          var chartDom1 = document.getElementById('block_choice');
          var myChart1 = echarts.init(chartDom1);
          var option5 = {
            tooltip: { trigger: 'axis' },
            legend: {
            },
            toolbox: {
              show: true,
              feature: {
                dataZoom: { yAxisIndex: 'none' },
                dataView: { readOnly: false },
                magicType: { type: ['line', 'bar'] },
                restore: {},
                saveAsImage: {}
              }
            },
            xAxis: {
              type: 'category',
              boundaryGap: false,
              data: #{x_axis.to_json.html_safe}
            },
            yAxis: { type: 'value' },
            series: #{raw(y_axis.to_json)},
          };
          option5 && myChart1.setOption(option5);
          // 监听点击事件
          myChart1.on('click', function(params) {
            var seriesIndex = params.seriesIndex;
            var dataIndex = params.dataIndex;
            option5.series[seriesIndex].data = null;
            myChart1.setOption(option5);
          });
          myChart1.on('mouseover', function(params) {
            console.log(params.seriesName);
          });
        JS
      end
    end
  end
end

def trade_date(x)
  days = x < 10 ? x + 20 : x * 2.3
  sse = $TusharePro.tushare_pro("trade_cal", "exchange": "SSE", "start_date": (Time.now - days.day).strftime("%Y%m%d"), "end_date": (Time.now).strftime("%Y%m%d")).select { |sse| sse["is_open"] == 1 }
  sse[x - 1]["cal_date"]
end